from typing import Annotated
from fastapi.security import OAuth2PasswordBearer
from jwt.exceptions import InvalidTokenError
from pydantic import ValidationError
from app.core.config import settings
from sqlalchemy.ext.asyncio import AsyncSession as Session
from fastapi import Depends, HTTPException, status
from app.core.session import get_db
import jwt
from app.models.uc.user import User
from app.core import security
from app.schemas.uc.auth import TokenPayload
from app.crud.uc.user import get_user_by_id
from app.core.logger import logger

reusable_oauth2 = OAuth2PasswordBearer(
    tokenUrl=f"{settings.API_V1_STR}/auth/login"
)

SessionDep = Annotated[Session, Depends(get_db)]
TokenDep = Annotated[str, Depends(reusable_oauth2)]

# 获取当前用户
async def get_current_user(session: SessionDep, token: TokenDep) -> User:
    try:
        payload = jwt.decode(
            token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
        )
        token_data = TokenPayload(**payload)
    except (InvalidTokenError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    logger.info(f"token_data sub: {token_data.sub}")
    user = await get_user_by_id(session=session, uid=token_data.sub)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    if user.status != 0:
        raise HTTPException(status_code=400, detail="Inactive user")
    return user

CurrentUser = Annotated[User, Depends(get_current_user)]

async def get_current_superuser(current_user: CurrentUser) -> User:
    if current_user.isSuper:
        raise HTTPException(status_code=403, 
                            detail="The user doesn't have enough privileges")
    return current_user

CurrentSuperuser = Annotated[User, Depends(get_current_superuser)]
